﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Utils;
using System.Windows.Input;
using System.IO;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;

namespace MoodLaZik.ViewModel
{
	class MainWindow : Utils.ViewModelBase
    {
        private String m_selectedMediaPath;
		public String SelectedMediaPath { get; set; }
		private bool m_mediaOpenedInit;
		private bool m_mediaIsPlaying;
		private bool m_mediaIsPaused;
		Timer m_seekTimer;
		private Double m_currentSeekerValue;
		public Double CurrentSeekerValue
		{
			get
			{
				return (m_currentSeekerValue);
			}
			set
			{
				if (value != m_currentSeekerValue)
				{
					m_currentSeekerValue = value;
					this.OnPropertyChanged("CurrentSeekerValue");
				}
			}
		}
		private Double m_maximumSeekerValue;
		public Double MaximumSeekerValue
		{
			get
			{
				return (m_maximumSeekerValue);
			}
			set
			{
				if (value != m_maximumSeekerValue)
				{
					m_maximumSeekerValue = value;
					this.OnPropertyChanged("MaximumSeekerValue");
				}
			}
		}

		private ICommand m_playMediaCommand;
		public ICommand PlayMediaCommand
		{
			get
			{
				if (m_playMediaCommand == null)
					m_playMediaCommand = new RelayCommand<object>(this.PlayMedia, this.CanPlayMedia);
				return (m_playMediaCommand);
			}
		}

		private ICommand m_pauseMediaCommand;
		public ICommand PauseMediaCommand
		{
			get
			{
				if (m_pauseMediaCommand == null)
					m_pauseMediaCommand = new RelayCommand<object>(this.PauseMedia, this.CanPauseMedia);
				return (m_pauseMediaCommand);
			}
		}

		private ICommand m_stopMediaCommand;
		public ICommand StopMediaCommand
		{
			get
			{
				if (m_stopMediaCommand == null)
					m_stopMediaCommand = new RelayCommand<object>(this.StopMedia, this.CanStopMedia);
				return (m_stopMediaCommand);
			}
		}

		private ICommand m_prevMediaCommand;
		public ICommand PrevMediaCommand
		{
			get
			{
				if (m_prevMediaCommand == null)
					m_prevMediaCommand = new RelayCommand<object>(this.PrevMedia, this.CanPrevMedia);
				return (m_prevMediaCommand);
			}
		}

		private ICommand m_nextMediaCommand;
		public ICommand NextMediaCommand
		{
			get
			{
				if (m_nextMediaCommand == null)
					m_nextMediaCommand = new RelayCommand<object>(this.NextMedia, this.CanNextMedia);
				return (m_nextMediaCommand);
			}
		}

		public MainWindow()
		{
			m_selectedMediaPath = "Riding Alone For Thousands Of Miles - love song.mp3";
			m_mediaOpenedInit = false;
			m_mediaIsPlaying = false;
			m_mediaIsPaused = false;
			m_seekTimer = new Timer();
			m_seekTimer.Tick += new EventHandler(TimerEventProcessor);
			m_seekTimer.Interval = 1000;
			m_currentSeekerValue = 0;
			m_maximumSeekerValue = 1;
            m_env = m_mood = m_place = m_personnality = m_weather = String.Empty;
            MoodLaZik.Model.XmlManipulator._infos = new Dictionary<string, string>();
		}

		private void TimerEventProcessor(Object myObject, EventArgs myEventArgs)
		{
			if (m_mediaIsPlaying == true)
				CurrentSeekerValue++;
			//if (CurrentSeekerValue >= MaximumSeekerValue)
			//	this.media_MediaEnded(null, null);
		}

		public bool CanPlayMedia(object _parameter)
		{
			return (m_selectedMediaPath != "" && !m_mediaIsPlaying);
		}
		public void PlayMedia(object _parameter)
		{
			MediaElement media;

			if (_parameter is MediaElement)
				media = _parameter as MediaElement;
			else
				return;

			if (m_mediaOpenedInit == false)
			{
				media.MediaOpened += new RoutedEventHandler(media_MediaOpened);
				media.MediaEnded += new RoutedEventHandler(media_MediaEnded);
				media.MediaFailed += new EventHandler<ExceptionRoutedEventArgs>(media_MediaFailed);
				m_mediaOpenedInit = true;
			}

			if (m_mediaIsPlaying == false && m_mediaIsPaused == false)
			{
				if (!m_mediaIsPaused)
				{
					try
					{
						media.LoadedBehavior = MediaState.Manual;
						media.UnloadedBehavior = MediaState.Manual;
						media.Source = new Uri(m_selectedMediaPath, UriKind.RelativeOrAbsolute);
						media.Play();
						m_seekTimer.Stop();
					}
					catch (Exception e)
					{
						System.Windows.Forms.MessageBox.Show("Error: Cannot play the file: " + m_selectedMediaPath + ": " + e.Message);
						return;
					}
				}
				else
				{
					System.Windows.Forms.MessageBox.Show("Cannot open " + m_selectedMediaPath);
					return;
				}
			}
			else
			{
				media.Play();
				m_seekTimer.Start();
			}

			m_mediaIsPlaying = true;
			m_mediaIsPaused = false;
		}

		public void media_MediaEnded(object sender, RoutedEventArgs e)
		{
			//m_selectedMediaPath = "";
			(sender as MediaElement).Stop();
			m_seekTimer.Stop();
			CurrentSeekerValue = 0;
			m_mediaIsPlaying = false;
			m_mediaIsPaused = false;
		}
		public void media_MediaOpened(object sender, RoutedEventArgs e)
		{
			MediaElement mediaElement = sender as MediaElement;
			if (mediaElement == null)
				return;
			//var tl = new MediaTimeline(mediaElement.Source);
			//mediaElement.Clock = tl.CreateClock(true) as MediaClock;
			if (mediaElement.NaturalDuration.HasTimeSpan)
			{
				MaximumSeekerValue = mediaElement.NaturalDuration.TimeSpan.TotalSeconds;
				m_seekTimer.Start();
			}
		}

		public void media_MediaFailed(object sender, RoutedEventArgs e)
		{
			System.Windows.MessageBox.Show("Error: The media player can't read the file: " + (sender as MediaElement).Source.AbsolutePath);
		}

		public bool CanPauseMedia(object _parameter)
		{
			return (m_mediaIsPlaying && !m_mediaIsPaused);
		}
		public void PauseMedia(object _parameter)
		{
			MediaElement mediaElement;
			if (_parameter is MediaElement)
				mediaElement = _parameter as MediaElement;
			else
				return;

			mediaElement.Pause();
			m_seekTimer.Stop();

			m_mediaIsPlaying = false;
			m_mediaIsPaused = true;
		}

		public bool CanStopMedia(object _parameter)
		{
			return (m_selectedMediaPath != "" && (m_mediaIsPlaying == true || m_mediaIsPaused == true));
		}
		public void StopMedia(object _parameter)
		{
			MediaElement mediaElement;
			if (_parameter is MediaElement)
				mediaElement = _parameter as MediaElement;
			else
				return;

			mediaElement.LoadedBehavior = MediaState.Manual;
			mediaElement.UnloadedBehavior = MediaState.Manual;
			mediaElement.Stop();
			m_seekTimer.Stop();

			m_mediaIsPlaying = false;
			m_mediaIsPaused = false;
		}

		public bool CanPrevMedia(object _parameter)
		{
			return (false);
		}
		public void PrevMedia(object _parameter)
		{
		}

		public bool CanNextMedia(object _parameter)
		{
			return (false);
		}
		public void NextMedia(object _parameter)
		{
        }

        // Infos looks like this -> "ENVIRONMENT:LOUDY/HOUR:2-4/MOOD:HAPPY/PLACE:HOME/PERSONNALITY:AGGRESSIVE/WEATHER:SUNNY";
        #region Fields
            private String m_env, m_mood, m_place, m_personnality, m_weather;
        #endregion

        #region Properties
            public String Env
            {
                get { return m_env; }
                set
                {
                    if (m_env == value) return;
                    m_env = value;
                    if (m_env != null) MoodLaZik.Model.XmlManipulator._infos["ENVIRONMENT"] = m_env;
                    OnPropertyChanged("Env");
                }
            }
            public String Mood
            {
                get { return m_mood; }
                set
                {
                    if (m_mood == value) return;
                    m_mood = value;
                    if (m_mood != null) MoodLaZik.Model.XmlManipulator._infos["MOOD"] = m_mood;
                    OnPropertyChanged("Mood");
                }
            }
            public String Place
            {
                get { return m_place; }
                set
                {
                    if (m_place == value) return;
                    m_place = value;
                    if (m_place != null) MoodLaZik.Model.XmlManipulator._infos["PLACE"] = m_place;
                    OnPropertyChanged("Place");
                }
            }
            public String Personnality
            {
                get { return m_personnality; }
                set
                {
                    if (m_personnality == value) return;
                    m_personnality = value;
                    if (m_personnality != null) MoodLaZik.Model.XmlManipulator._infos["PERSONNALITY"] = m_personnality;
                    OnPropertyChanged("Personnality");

                }
            }
            public String Weather
            {
                get { return m_weather; }
                set
                {
                    if (m_weather == value) return;
                    m_weather = value;
                    if (m_weather != null) MoodLaZik.Model.XmlManipulator._infos["WEATHER"] = m_weather;
                    OnPropertyChanged("Weather");

                }
            }
        #endregion
    }
}
